#   This file is part of emesene.
#
#    Eval plugin is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    Eval plugin is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with emesene; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

VERSION = '0.2'
import gtk
import Plugin
import urllib
import ConversationManager

class PygTranslate():
	
	def __init__(self):
		pass
	
	class AppURLopener(urllib.FancyURLopener):
		def __init__(self, *args):
			self.version = 'Mozilla/5.0'
			apply(urllib.FancyURLopener.__init__, (self,) + args)

	def to_url_hex(self,str):
		'''
		Converts a string to url style hex like %** 
		'''
		'''
		init_hex = str.encode('hex')
		endStr = ''
		n=0
		while n < len(init_hex):
			if n % 2 == 0:
				#n is even number
				endStr += '%'
			
			endStr += init_hex[n]
			n += 1

		return endStr
		'''
		str = str.replace('*', '')
		str = str.replace(' ', '%20')
		str = str.replace('&', '%26')
		
		return str
		
	def from_url_hex(self,str):
		'''
		This function needs to be improved!
		Converts any \u00** hex values to normal text.
		'''
		# Replace google format for: '.
		str = str.replace('\u0026#39;', "'")
		
		n=0
		retBuff = ''
		strLen = len(str)

		while n < strLen:
			#better me!
			#construct buffer to keep range of indexes.
			if (n >= (strLen - 4)) and (str[n] != '\\'):
				retBuff += str[n]
				n += 1
			else:
				
				if str[n:n+4] == '\u00':
					
					retBuff += str[n+4:n+6].decode('hex')
					n += 5
				else:
					retBuff += str[n]
				n += 1
			
		return retBuff

	def get_trans_text(self,str):
		'''
		Rettrives text translation from html string.
		'''

		before_constant = 'translatedText":"'
		after_constant = '"}, '

		bef,mid,aft = str.partition(before_constant)

		bef,mid,end = aft.partition(after_constant)

		#Convert all google format hex to normal text.
		return self.from_url_hex(bef)

	def get_trans_key(self,str):
		'''
		Rettrives translation language key from string.
		'''

		before_constant = ',{"language":"'
		after_constant = '","isReliable"'

		bef,mid,aft = str.partition(before_constant)

		bef,mid,end = aft.partition(after_constant)
		
		#Convert all google format hex to normal text.
		return self.from_url_hex(bef)

	def translate(self,init_translate, from_lanKey, to_lanKey):
		'''
		Translate from lang1 to lang2. 

		Returns: translated text as string.

		Example parameters: 
		from_lanKey = 'en'
		to_lanKey = 'fr'
		init_translate = 'hello world'
		return value == 'Bonjour le monde'
		'''

		url = 'http://www.google.com/uds/Gtranslate?callback=google.language.callbacks.id100&context=22&q=' + self.to_url_hex(init_translate) + '&langpair=' + from_lanKey + '%7C' + to_lanKey + '&key=notsupplied&v=1.0'
		urllib._urlopener = self.AppURLopener()
		ret =  urllib._urlopener.open(url).read()
		
		#Rip translated text from html.
		return self.get_trans_text(ret)

	def get_text_lang(self,orig_text):
		'''
		Get's the language of orig_text.
		'''
		url = 'http://www.google.com/uds/GlangDetect?callback=google.language.callbacks.id100&context=22&q=' + to_url_hex(orig_text) + '&key=notsupplied&v=1.0'
		urllib._urlopener = AppURLopener()

		ret =  urllib._urlopener.open(url).read()
		
		return self.get_trans_key(ret)

	def lang_key_converter(self,str):
		'''
		Given either the key or the vlaue for the dictionary languages
		the coresponding key or value is returned.
		
		Example usage 1:
		str = 'fr'
		Return value == 'french'
		
		Example usage 2:
		str = 'french'
		Return value == 'fr'
		'''
		
		self.languages = {
		'french' : 'fr',
		'german' : 'de',
		'italian' : 'it',
		'spanish' : 'es',
		'russian' : 'ru',
		'portuguese': 'pt',
		'dutch' : 'nl',
		'japanese' : 'ja',
		}
		
		if self.languages.has_key(str.lower()):
			return self.languages[str.lower()]
		else:
			for key in self.languages.keys():
				if self.languages[key] == str.lower():
					return key
	

class TranslateButton(gtk.ToolButton):
	
    def __init__(self, conversation,translator,pygInstance):
    	gtk.ToolButton.__init__(self,  gtk.STOCK_CONVERT)
    	self.conversation = conversation
    	self.pygInstance = pygInstance
    	conversation.fromLanguage = 'spanish'
    	conversation.toLanguage = 'italian'
    	self.languages = ['french','german','italian','spanish','russian','portuguese','dutch','japanese']
    	self.translator = translator
    	self.conversation.translationEnabled = False
            
    def configTranslator(self, widget=None, conversation=None):
        l = []
        # name, optionType, label, description, value, options
        l.append(Plugin.Option('fromLanguage', list, _('From:'), \
            _('Select the language to be translated'),conversation.fromLanguage, \
            self.getFromLanguage()))
        l.append(Plugin.Option('toLanguage', list, _('To:'), \
            _('Select the language to translate'),conversation.toLanguage, \
            self.getToLanguage()))
        l.append(Plugin.Option('enableTranslation', bool, 
            _('Enable Translation'), 
            _('Enable the translations on this window'), 
            (self.conversation.translationEnabled)))

        #Run up your config
        self.configWindow = Plugin.ConfigWindow(_('Translator'),l)
        response = self.configWindow.run()
        
        if response != None:
            self.conversation.fromLanguage = response['fromLanguage'].value;
            self.conversation.toLanguage = response['toLanguage'].value;
            self.conversation.translationEnabled = response['enableTranslation'].value;
    
    def do_receive_message (self, mail, nick, message, format, charset):
        '''Receive a message from'''
        self.real_do_receive_message(mail , nick, self.translateText(message), format, charset)
        
    def real_do_receive_message(self, mail, nick, message, format, charset):
        '''This method is called when a message is received
        in the switchboard'''

        self.conversation.doMessageWaiting(mail)

        if self.conversation.config.user['autoReply'] and not self.conversation.autoreplySent:
            msg = self.conversation.config.user['autoReplyMessage']

            # no gettext here, it's a semi standard way
            # to identify automessages
            self.conversation.switchboard.sendMessage('AutoMessage: ' + msg)
            self.conversation.appendOutputText(None, 'AutoMessage: %s\n' % msg, \
                'information')
            self.conversation.autoreplySent = True

        if message is not None:
            self.conversation.appendOutputText(mail, message, 'incoming', \
                self.conversation.parseFormat(mail, format))
    
    def translateText(self,message):
        if self.translator.enabled and self.conversation.translationEnabled :
    	    return self.pygInstance.translate(message,self.pygInstance.lang_key_converter(self.conversation.fromLanguage),self.pygInstance.lang_key_converter(self.conversation.toLanguage))
        return message
    
           
    def getFromLanguage(self):
        ''' Ask pytrans for the languages that can be translated'''
        return self.languages
    
    def getToLanguage(self):
        ''' Ask pytrans for the languages to translate'''
        return self.languages
        
class MainClass(Plugin.Plugin):
    '''Main plugin class'''
    
    def __init__(self, controller, msn):
        '''Contructor'''
        Plugin.Plugin.__init__(self, controller, msn)
        
        self.description = _('Translate text using the Google Translator')
        self.authors = { 'Guiman' : 'alvarola@gmail.com'}
        self.website = 'emesene.org'
        self.displayName = _('Google Translate')
        self.name = 'Translator'
        self.controller = controller
        self.pygtrans = PygTranslate()
        
        self.config = self.controller.config
        self.config.readPluginConfig(self.name)
                      
    def start(self):
        '''start the plugin'''
        
        for conversation in self.getOpenConversations():
        	self.add_button(conversation=conversation)
        	
        self.signalopen = self.controller.conversationManager.connect('new-conversation-ui', self.add_button)
        self.signalclose = self.controller.conversationManager.connect('close-conversation-ui', self.remove_button)
        self.enabled = True
    
    def stop(self):    
        '''stop the plugin'''
        for conversation in self.getOpenConversations():
            self.remove_button(conversation=conversation)
                    
        self.controller.conversationManager.disconnect(self.signalopen)
        self.controller.conversationManager.disconnect(self.signalclose)
        self.enabled = False

    
    def add_button(self, conversationmanager=None, conversation=None, win=None):
        button = TranslateButton(conversation,self,self.pygtrans)
        button.connect('clicked', button.configTranslator,conversation)
        conversation.do_receive_message = button.do_receive_message
        button.show()
        toolbar = conversation.ui.input.toolbar
        toolbar.add(button)
    
    def remove_button(self, conversationmanager=None, conversation=None, win=None):
        for button in conversation.ui.input.toolbar.get_children():
            if type(button) == TranslateButton:
                conversation.ui.input.toolbar.remove(button)
                button.destroy()
        
    def check(self):
        return (True, 'Ok')
        
    
